<script lang="ts" setup name="BaseApi">
// import {
//   ref,
//   onMounted,
//   shallowRef,
//   triggerRef,
//   toRef,
//   customRef,
//   isRef,
//   reactive,
//   shallowReactive,
//   readonly,
// } from 'vue'

type ObjectUser = {
  userInfo: {
    name: string
  }
  address: string
}

const refObj = ref<{ userInfo: { name: string } }>({ userInfo: { name: 'zhangsan' } })
const shallowRefObj = shallowRef({ userInfo: { name: 'zhangsan' }, address: '123666' })
const objname = shallowRef('name')
let reactiveObj = reactive<ObjectUser>({ userInfo: { name: 'zhangsan' }, address: '123666' })
// const { address } = toRefs(reactiveObj)
const address = toRef(reactiveObj, 'address')
const reactiveArr: unknown[] = reactive([1, 2, 3])
const shallowReactiveObj = shallowReactive({ userInfo: { name: 'zhangsan' }, address: '123666' })
const readonlyObj = readonly(reactiveObj)

const testToRefs = reactive({ name: 'name', age: 18 })
// const { name } = toRefs(testToRefs)
const name = toRef(testToRefs, 'name')

onMounted(() => {
  console.log(isRef(shallowRefObj))
})

const changeShallowRef = () => {
  shallowRefObj.value.userInfo.name = 'lisi'
  triggerRef(shallowRefObj) //等同于触发一次ref定义的值的更新
}

const mySelfRef = <T,>(value: T) => {
  let timer: NodeJS.Timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track() //收集依赖
        return value
      },
      set(newValue) {
        clearTimeout(timer)
        timer = setTimeout(() => {
          value = newValue
          console.log('触发更新')
          trigger() //触发更新
        }, 1000)
      },
    }
  })
}
const objname2 = mySelfRef('name')

const changeReactiveArr = () => {
  reactiveArr[0] = 666 + new Date().getTime()
}

const changeReactiveObj = () => {
  reactiveObj = { userInfo: { name: 'wangwu' }, address: '123666' }
}

const changeReactivePer = () => {
  testToRefs.name = 'zhaoliu'
}
</script>

<template>
  1
  <div>
    <!-- params需要在路由后匹配也就是动态路由参数才生效 query需在路由后匹配 path/name-query name-params -->
    <router-link :to="{ path: 'tailwindcsstemp', query: { id: 123 } }">用户主页</router-link>
    <h1 :style="{ fontSize: '50px' }">ref&reactive相关api语法与使用</h1>
    <h1>ref:{{ refObj.userInfo.name }}</h1>
    <button @click="refObj.userInfo.name = 'lisi'">changeref</button>
    <h1>shallowRef改不了:{{ shallowRefObj.userInfo.name }}住在{{ shallowRefObj.address }}</h1>
    <button @click="changeShallowRef">changeshallowRefDeep</button>
    <h1>shallowRef可以改:{{ objname }}</h1>
    <button @click="objname = '666胡同'">changeshallowRef</button>
    <h1>结构响应式对象并保持子集的响应式：{{ address }}</h1>
    <button @click="address = '888巷子'">结构ref保持响应式</button>
    <h1>mySelfRef:{{ objname2 }}</h1>
    <button @click="objname2 = '888胡同'">mySelfRef</button>
    <h1>reactiveObj:{{ reactiveObj.userInfo.name }}</h1>
    <button @click="changeReactiveObj">changereactiveObj</button>
    <h1>reactiveArr:{{ reactiveArr[0] }}</h1>
    <button @click="changeReactiveArr">changereactiveArr</button>
    <h1>shallowReactive:{{ shallowReactiveObj.userInfo.name }}</h1>
    <button @click="shallowReactiveObj.userInfo.name = 'zhaoliu'">changeshallowReactive</button>
    <h1>readonly 引用reactive变量:{{ readonlyObj.userInfo.name }}</h1>
    <button @click="changeReactivePer">点击测试torefs</button>
    <h1>testtorefs:{{ testToRefs.name }}:>>>>{{ name }}</h1>
    <!--  <button @click="readonlyObj.userInfo={name:'zhaoliu'}">readonlyChangeTest</button> -->
    <ul>
      1.如果是shallowRef，那么只能改变第一层的数据，对象属性也改不了，如果是ref，那么可以改变所有层的数据<br />
      2.如果shallowRef和ref混用(类似reactshallowReactive)，那么点击一次shallowRef，再点击一次ref，那么shallowRef和ref的属性都会改变<br />
      3.硬要shallowRef改变对象属性，那么可以使用triggerRef
      <br />
      4.如果要自定义ref，那么可以使用customRef
      <br />
      5.react是proxy代理的对象 不能直接改变reactive的值，只能改变reactive的引用
      <br />
      6.readonly只能保护第一层数据，如果是对象，那么对象属性可以改变，如果是数组，那么数组的元素可以改<br />
      7.toRef和toRefs可以将reactive对象的属性转换为ref对象，但是toRef只能转换一个属性，toRefs可以转换多个属性
      常用于结构reactive对象并保持响应式
      <br />
      8.toRaw可以将reactive对象转换为普通对象，但是toRaw只能转换reactive对象，不能转换ref对象<br />
      9.markRaw可以将对象标记为不可响应，但是markRaw只能标记对象，不能标记数组<br />
      10.shallowReactive和shallowRef只能保护第一层数据，如果是对象，那么对象属性可以改变，如果是数组，那么数组的元素可以改<br />
    </ul>
  </div>
</template>

<style scoped lang="scss"></style>
